const path = require('path')
const EslintWebpackPlugin = require('eslint-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')
const TerserWebpackPlugin = require('terser-webpack-plugin')
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin')
const CopyPlugin = require("copy-webpack-plugin");
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');

// 不同的环境loader不同，怎么判断呢
// 获取cross-env定义的环境变量
const isProduction = process.env.NODE_ENV === "production"

const getStyleLoaders = (pre) => {
    return [
        // 判断环境
        isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
        'css-loader',
        {
            loader: 'postcss-loader',
            options: {
                postcssOptions: {
                    plugins: ['postcss-preset-env'],
                }
            }
        },
        pre && {
            loader: pre,
            options: pre === 'less-loader' ? {
                // antd自定义主题配置
                // 主题色文档：https://ant.design/docs/react/customize-theme-cn#Ant-Design-%E7%9A%84%E6%A0%B7%E5%BC%8F%E5%8F%98%E9%87%8F
                lessOptions: {
                    modifyVars: { "@primary-color": "#1DA57A" },
                    javascriptEnabled: true,
                },
            } : {},
        },
    ].filter(Boolean)
}

module.exports = {
    entry: './src/main.js',
    output: {
        path: isProduction ? path.resolve(__dirname, '../dist') : undefined,
        filename: isProduction ? 'static/js/[name].[contenthash:10].js' : 'static/js/[name].js',
        chunkFilename: isProduction ? 'static/js/[name].[contenthash:10].chunk.js' : 'static/js/[name].chunk.js',
        assetModuleFilename: 'static/media/[hash:10][ext][query]',
        clean: true, // 可改可不改，开发模式为true也可以
    },
    module: {
        rules: [
            {
                // 处理css
                test: /\.css$/,
                use: getStyleLoaders()
            },
            {
                // 处理less
                test: /\.less$/,
                use: getStyleLoaders('less-loader')
            },
            {
                // 处理sass
                test: /\.s[ac]ss$/,
                use: getStyleLoaders('sass-loader')
            },
            {
                // 处理stylus
                test: /\.styl$/,
                use: getStyleLoaders('stylus-loader')
            },
            {
                // 处理图片
                test: /\.(jpe?g|png|gif|webp|svg)$/,
                type: 'asset',
                parser: {
                    dataUrlCondition: {
                        maxSize: 10 * 1024,
                    }
                }
            },
            {
                // 处理其他资源
                test: /\.(woff2|ttf)$/,
                type: "asset/resource",
            },
            {
                // 处理js
                test: /\.jsx?$/,
                include: path.resolve(__dirname, '../src'),
                loader: 'babel-loader',
                options: {
                    cacheDirectory: true,
                    cacheCompression: false,
                    plugins: [!isProduction && 'react-refresh/babel'].filter(Boolean), // 生产模式不需要
                }
            }
        ]
    },
    // 处理html
    plugins: [
        new EslintWebpackPlugin({
            context: path.resolve(__dirname, '../src'),
            exclude: 'node_modules',
            cache: true,
            cacheLocation: path.resolve(__dirname, '../node_modules/.cache/.eslintcache'),
        }),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, '../public/index.html')
        }),
        isProduction && new MiniCssExtractPlugin({
            filename: 'static/css/[name].[contenthash:10].css',
            chunkFilename: 'static/css/[name].[contenthash:10].chunk.css'
        }),
        isProduction && new CopyPlugin({
            patterns: [
                // 改为绝对路径，相对路径可能出问题
                {
                    from: path.resolve(__dirname, '../public'),
                    to: path.resolve(__dirname, '../dist'),
                    // 忽略index.html文件(因为上面HtmlWebpackPlugin已经有一份了)
                    globOptions: {
                        ignore: ["**/index.html"],
                    }
                },
            ],
        }),
        !isProduction && new ReactRefreshWebpackPlugin(),
    ].filter(Boolean), // 有可能有，有可能没有的插件都要过滤
    mode: isProduction ? 'production' : 'development',
    devtool: isProduction ? 'source-map' : 'cheap-module-source-map',
    optimization: {
        splitChunks: {
            chunks: 'all',
            cacheGroups: {
                // react react-dom react-router-dom 一起打包成一个js文件
                react: {
                    test: /[\\/]node_modules[\\/]react(.*)?[\\/]/,
                    name: 'chunk-react',
                    priority: 40,
                },
                // antd 单独打包
                antd: {
                    test: /[\\/]node_modules[\\/]antd[\\/]/,
                    name: 'chunk-antd',
                    priority: 30,
                },
                // 剩下的node_modules单独打包
                libs: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'chunk-libs',
                    priority: 20,
                },
            }
        },
        runtimeChunk: {
            name: (entrypoint) => `runtime~${entrypoint.name}.js`,
        },
        minimize: isProduction, // 是否需要进行压缩 
        minimizer: [
            new CssMinimizerWebpackPlugin(),
            new TerserWebpackPlugin(),
            new ImageMinimizerPlugin({
                minimizer: {
                    implementation: ImageMinimizerPlugin.imageminGenerate,
                    options: {
                        plugins: [
                            ["gifsicle", { interlaced: true }],
                            ["jpegtran", { progressive: true }],
                            ["optipng", { optimizationLevel: 5 }],
                            [
                                "svgo",
                                {
                                    plugins: [
                                        "preset-default",
                                        "prefixIds",
                                        {
                                            name: "sortAttrs",
                                            params: {
                                                xmlnsOrder: "alphabetical",
                                            },
                                        },
                                    ],
                                },
                            ],
                        ],
                    },
                },
            }),
        ]
    },
    // 解析模块加载选项
    resolve: {
        // 自动补全文件拓展名
        extensions: [".jsx", ".js", ".json"]
    },
    devServer: {
        host: 'localhost',
        port: 3000,
        open: true,
        hot: true, //开启HMR
        historyApiFallback: true, // 解决前端路由刷新404问题
    },
    performance: flase, // 关闭性能分析，提升打包速度
}